package cn.nexttec.noteplayer.common

import android.util.Log
import com.arthenica.ffmpegkit.FFmpegKit
import java.io.File

object FFmpegUtil {

    private const val TAG = "FFmpegUtil"

    // 通用执行器：支持输出路径校验
    private fun runCommand(
        commandList: List<String>,
        expectedOutputPath: String? = null,
        onSuccess: () -> Unit,
        onError: (String) -> Unit
    ) {
        fun quoteIfNeeded(s: String): String = if (s.contains(" ")) "\"$s\"" else s

        val command = commandList.joinToString(" ") { quoteIfNeeded(it) }
        Log.d(TAG, "执行 FFmpeg 命令: $command")

        FFmpegKit.executeAsync(command) { session ->
            val failMsg = session.failStackTrace ?: session.allLogsAsString

            val fileSuccess = expectedOutputPath?.let {
                val file = File(it)
                file.exists() && file.length() > 0
            } ?: false

            if (fileSuccess) {
                Log.d(TAG, "文件生成成功: $expectedOutputPath")
                onSuccess()
            } else {
                Log.e(TAG, "FFmpeg 执行失败: $failMsg")
                onError("FFmpeg 执行失败: $failMsg")
            }
        }
    }

    /** 截取视频片段（无重编码） */
    fun clip(
        inputPath: String,
        startMs: Long,
        durationMs: Long,
        outputPath: String,
        onSuccess: () -> Unit,
        onError: (String) -> Unit
    ) {
        val command = listOf(
            "-ss", (startMs / 1000.0).toString(),
            "-i", inputPath,
            "-t", (durationMs / 1000.0).toString(),
            "-c", "copy",
            "-y", outputPath
        )
        runCommand(command, expectedOutputPath = outputPath, onSuccess, onError)
    }

    /** 提取音频为 MP3（重编码） */
    fun extractAudioToMp3(
        inputPath: String,
        outputPath: String,
        onSuccess: () -> Unit,
        onError: (String) -> Unit
    ) {
        val command = listOf(
            "-i", inputPath,
            "-vn",
            "-acodec", "libmp3lame",
            "-q:a", "2",
            "-y", outputPath
        )
        runCommand(command, expectedOutputPath = outputPath, onSuccess, onError)
    }

    /** 截取音频片段（转 mp3） */
    fun clipAudioSegment(
        inputPath: String,
        startMs: Long,
        durationMs: Long,
        outputPath: String,
        onSuccess: () -> Unit,
        onError: (String) -> Unit
    ) {
        val command = listOf(
            "-ss", (startMs / 1000.0).toString(),
            "-i", inputPath,
            "-t", (durationMs / 1000.0).toString(),
            "-acodec", "libmp3lame",
            "-q:a", "2",
            "-y", outputPath
        )
        runCommand(command, expectedOutputPath = outputPath, onSuccess, onError)
    }

    /** 从视频中截取某一帧保存为图片 */
    fun captureFrame(
        inputPath: String,
        timestampMs: Long,
        outputImagePath: String,
        onSuccess: () -> Unit,
        onError: (String) -> Unit
    ) {
        val timestamp = formatTimeMs(timestampMs)
        val command = listOf(
            "-ss", timestamp,
            "-i", inputPath,
            "-vframes", "1",
            "-q:v", "2",
            "-y", outputImagePath
        )
        runCommand(command, expectedOutputPath = outputImagePath, onSuccess, onError)
    }

    /** 毫秒转 ffmpeg 时间格式：123456 → 00:02:03.456 */
    private fun formatTimeMs(ms: Long): String {
        val totalSeconds = ms / 1000
        val milliseconds = ms % 1000
        val seconds = totalSeconds % 60
        val minutes = (totalSeconds / 60) % 60
        val hours = totalSeconds / 3600
        return String.format("%02d:%02d:%02d.%03d", hours, minutes, seconds, milliseconds)
    }
}
